<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title>闭包</title>
  <meta name="generator" content="editplus" />
  <meta name="author" content="" />
  <meta name="keywords" content="" />
  <meta name="description" content="" />
  <script src="../jquery-1.8.2.js"></script>
  <script>
/**
 * 支持内部函数的语言，则允许开发者在必要的地方集合小型实用的函数，以避免的命名空间的干扰。
 * 递归但却带有非递归 API 包装的算法通常最适合通过内部函数来表达。
 * 逃脱：
 * 1.内部函数指定给一个全局变量
 * 2.父函数返回值来“营救出”内部函数的引用
 * 每当通过引用或其它方式调用内部函数，都会创建一个新的 innerVar 变量。
 *
 * 当内部函数在定义它的作用域的外部被引用时，就创建了该内部函数的一个闭包。我们称既不是内部函数局部变量，也不是其参数的变量为
 * **自由变量**，称外部函数的调用环境为封闭闭包的环境。如果内部函数引用了位于外部函数中的变量，相当于授权该变量能够被延迟使用。
 * 因此，当外部调用完成后，这些变量的内存不会被释放，因为闭包仍然需要使用它们。
 * 事件处理程序同其它函数一样，也能够能够共享它们的封闭环境。
 * JS 会为一个新的内存驻留项（对象或函数）留出一块空间。
 * 由于闭包的原因，位于 outerFn() 中的所有变量都隐含地被 innerFn() 所引用。因此闭包会使意外地创建这些引用循环变得易如反掌。
 *
 */
$().ready(function() {
	jQuery.fn.print = function(message) {
		return this.each(function() {
			$('<div class="result"></div>').text(String(message)).appendTo($(this).find('.results'));
		});
	};
	function outerFn() {
		var outerVar = 0;
		function innerFn1() {
			outerVar++;
			console.log('(1) outerVar = ' + outerVar);
		}
		function innerFn2() {
			outerVar += 2;
			console.log('(2) outerVar = ' + outerVar);
		}
		return {'fn1': innerFn1, 'fn2': innerFn2};
	}
	var fnRef = outerFn();
	fnRef.fn1();
	fnRef.fn2();
	fnRef.fn1();
	var fnRef2 = outerFn();
	fnRef2.fn1();
	fnRef2.fn2();
	fnRef2.fn1();

	/*=====================================================================
	 *
	 *===================================================================*/
	var counter = 0;
	$('#click1').click(function() {
		counter++;
		console.log('counter = ' + counter);
		return false;
	});
	$('#click2').click(function() {
		counter--;
		console.log('counter = ' + counter);
		return false;
	});
	
	/*==============================================================
	 *
	 *
	 *=============================================================*/
	$('div').each(function(index) {
		function clickHandler() {
			console.log('index = ' + index);
			return false;
		}
		$(this).click(clickHandler);
	});
	
	/*=============================================================
	 *
	 * 意外的引用循环
	 *
	 *===========================================================*/
	function quoteOuterFn() {
		var quoteOuterVar = {};
		function quoteInnerFn() {
			alert(quoteOuterVar);
		}
	}
});
  </script>
 </head>

 <body>
  <div id="click1">click1</div>
  <div id="click2">click2</div>
 </body>
</html>
